//俄罗斯方块
//*****活动方块*****
class ActiveBlock {
	constructor(el, pool, nextEl){
		//活动方块的UI元素
		this.el = el;
		this.nextEl = nextEl;
	
		//方块池对象
		this.pool = pool;
	
		//总个数
		this.total = 0;
	
		//表示活动方块的坐标数据
		this.curBlock = {
			//一个json 对象。data 表示坐标集合，dataIdx表示索引下标
			//{	data: [],	dataIdx: 1}
		};	
	
		this.nextBlock = this.getBlockData()
	}

	static coordinatePool = [
		//上宝盖
		[
			[[1,4],[1,5],[1,6],[0,5]],
			[[0,5],[1,5],[2,5],[1,6]],
			[[1,4],[1,5],[1,6],[2,5]],
			[[1,4],[0,5],[1,5],[2,5]]
		],
		//横竖
		[
			[[0,3],[0,4],[0,5],[0,6]],
			[[0,4],[1,4],[2,4],[3,4]]
		],
		//方块
		[
			[[0,4],[1,4],[0,5],[1,5]]
		],
		//N型1
		[
			[[0,5],[1,5],[1,4],[2,4]],
			[[0,4],[0,5],[1,5],[1,6]]
		],
		//N型2
		[
			[[0,4],[1,4],[1,5],[2,5]],
			[[0,5],[0,6],[1,5],[1,4]]
		],
		//L型
		[
			[[1,4],[1,5],[1,6],[0,4]],
			[[0,5],[0,6],[1,5],[2,5]],
			[[0,4],[0,5],[0,6],[1,6]],
			[[0,6],[1,6],[2,6],[2,5]]
		],
	]

	getBlockData() {
		const shapesCount = ActiveBlock.coordinatePool.length
		// 随机选一个形状
		const index = Math.floor(Math.random() * shapesCount)
		let shape = ActiveBlock.coordinatePool[index]

		//纵坐标变为从下到上
		shape = JSON.parse(JSON.stringify(shape));
		for (const gensture of shape) {
			for (const unit of gensture) {
				unit[0] = 19 - unit[0]
			}
		}

		return {
			data: shape,
			dataIdx: Math.floor(Math.random() * shape.length)
		}
	}

	//生成下一个方块坐标
	next() {
		this.curBlock = JSON.parse(JSON.stringify(this.nextBlock))
		this.nextBlock = this.getBlockData()
		this.refreshUI();
		this.total++;
	}

	//方块旋转
	rotate(){
		if (this.canRotate()) {
			const count = this.curBlock.data.length
			this.curBlock.dataIdx = (this.curBlock.dataIdx +1) % count;	
			this.refreshBlockUI();
		}
	}

	//坠落
	fallDown(){
		let t = setInterval(this.move.bind(this), 0, 'down', () => {
			clearInterval(t)
		})
	}

	canMove(type) {
		let gensture = this.curBlock.data[this.curBlock.dataIdx]
		for (const unit of gensture) {
			var r = unit[0],
				c = unit[1];
			// 将要出界或者被堵
			switch(type) {
				case 'left':				
					if(c == 0 || this.pool.data[r][c - 1] == 1){
						return false
					}
					break
				case 'right':
					if(c == 9 || this.pool.data[r][c + 1] == 1){
						return false
					}
					break
				case 'down':
					if(r == 0 || this.pool.data[r - 1][c] == 1){
						return false
					}
					break
			}
		}
		return true;
	}

	/**
	 * 
	 * @param {*} type 
	 * @param {*} cb 下移：不能下移时的操作
	 */
	move(type, cb) {
		if (this.canMove(type)) {
			for (const gensture of this.curBlock.data) {
				for (const unit of gensture) {
					switch(type) {
						case 'left':
							unit[1]-- //纵坐标 -1
							break;
						case 'right':
							unit[1]++ //纵坐标 +1
							break;
						case 'down':
							unit[0]-- //横坐标 -1
							break;
					}
				}
			}
			this.refreshBlockUI();
		} else {
			if (type == 'down' && typeof cb === 'function') {
				cb()
			}
		}
	}

	canRotate(){
		const curIdx = this.curBlock.dataIdx
		let nextGesture = this.curBlock.data[(curIdx +1) % this.curBlock.data.length];
		for (const unit of nextGesture) {
			var r = unit[0],
				c = unit[1];			
			if(r < 0 || c < 0 || c > 9){
				return false;//1越界
			} else if (this.pool.data[r][c] == 1) {
				return false;//2.阻挡
			}
		}		
		return true;
	}

	//落到池子
	gotoPool(){
		var obj = this.curBlock;

		//1、更新池子数据
		const gensture = obj.data[obj.dataIdx]
		for (const unit of gensture) {
			var r = unit[0],
				c = unit[1];	
			this.pool.data[r][c] = 1;
		}
		
		//2、删除满行
		let rsum = 0
		//2.1更新后，检查该活动块所影响的行是否满行
		for (const unit of gensture) {
			var r = unit[0],
				c = unit[1],	
				rowdata = this.pool.data[r];
			if (rowdata.join('') === '1111111111') {
				rowdata.del = true
			}
		}
		
		//2.2删除满行
		for (r=19; r >=0; r--)
		{
			var row = this.pool.data[r];
			if(row.del === true) {
				this.pool.data.splice(r,1);
				this.pool.data.push(new Array(10));
				console.log("删除第几行："+r)
				rsum ++;
			}
		}

		this.pool.refreshUI();
	}
	
	refreshBlockUI(el = this.el, obj = this.curBlock) {
		el.innerHTML = "";

		for (var i=0; i<4; i++)
		{
			var item = obj.data[obj.dataIdx][i],
				r = item[0],
				c = item[1];
			var t = (19 - r) * unit;
			el.appendChild(genUnit(c, t));
		}

		//预览下一个方块
		obj = this.nextBlock;
		divNext.innerHTML = "";
		for (var i=0; i<4; i++)
		{
			var item = obj.data[obj.dataIdx][i],
				r = item[0],
				c = item[1] - 3;
			var t = (19 - r) * unit;
			divNext.appendChild(genUnit(c, t));
		}
	}

	refreshNextBlockUI(el, obj) {
		return this.refreshBlockUI(this.nextEl, this.nextBlock)
	}

	//坐标变化重新渲染UI(清除元素，重新添加)
	refreshUI(){
		this.refreshBlockUI()
		this.refreshNextBlockUI()
	}
}
